<link href="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<!------ Include the above in your HEAD tag ---------->
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r120/three.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.5.1/gsap.min.js"></script>
<script id="vertexShader" type="x-shader/x-vertex">
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix *
modelViewMatrix *
vec4(position,1.0);
}
</script>
<script id="fragmentShader" type="x-shader/x-fragment">
uniform sampler2D image;
uniform sampler2D displacement;
uniform float u_time;
uniform float u_progress;
uniform float u_mouse;
varying vec2 vUv;
void main() {
vec4 displace = texture2D(displacement, vUv);
vec2 displacedUV = vec2(vUv.x + u_progress * 0.1 * sin(vUv.y * 4.0 + u_time), vUv.y);
vec4 color = texture2D(image, displacedUV);
color.r = texture2D(image, displacedUV + vec2(0., 10.0 * 0.005) * (u_progress * 5.)).r;
color.g = texture2D(image, displacedUV + vec2(0., 10.0 * 0.007) * (u_progress * 2.)).g;
color.b = texture2D(image, displacedUV + vec2(0., 10.0 * 0.008) * (u_progress * 3.0)).b;
gl_FragColor = color;
}
</script>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
height: 100vh;
width: 100vw;
}
canvas {
height: 100%;
width: 100%;
}
const container = document.body;
let viewport = {
width: container.clientWidth,
height: container.clientHeight,
aspectRatio: container.clientWidth / container.clientHeight
};
const scene = new THREE.Scene();
scene.background = new THREE.Color(0xb0cec8);
const renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: false
});
renderer.setSize(viewport.width, viewport.height);
renderer.setPixelRatio = window.devicePixelRatio;
container.appendChild(renderer.domElement);
const FOV = 50;
const CAMERA_NEAR = 0.1;
const CAMERA_FAR = 160;
const ASPECT_RATIO = viewport.aspectRatio;
const camera = new THREE.PerspectiveCamera(
FOV,
ASPECT_RATIO,
CAMERA_NEAR,
CAMERA_FAR
);
camera.position.set(0, 0, 50);
{
const near = 1;
const far = 150;
const color = 0xb0cec8;
scene.fog = new THREE.Fog(color, near, far);
}
const sectionsInfo = [
{
images: [
"https://assets.codepen.io/2479807/grid-photo-4.jpg",
"https://assets.codepen.io/2479807/grid-photo-3.jpg",
"https://assets.codepen.io/2479807/grid-photo-2.jpg",
"https://assets.codepen.io/2479807/grid-photo-1.jpg"
],
title: "Januar"
},
{
images: [
"https://assets.codepen.io/2479807/scroll-1.jpg",
"https://assets.codepen.io/2479807/scroll-2.jpg",
"https://assets.codepen.io/2479807/scroll-3.jpg"
],
title: "Februar"
},
{
images: [
"https://assets.codepen.io/2479807/img-5.jpg",
"https://assets.codepen.io/2479807/img-6.jpg",
"https://assets.codepen.io/2479807/img-7.jpg",
"https://assets.codepen.io/2479807/img-8.jpg"
],
title: "Mars"
},
{
images: [
"https://assets.codepen.io/2479807/bike-1.jpg",
"https://assets.codepen.io/2479807/bike-2.jpg",
"https://assets.codepen.io/2479807/bike-3.jpg",
"https://assets.codepen.io/2479807/grid-photo-1.jpg"
],
title: "April"
}
];
const raycaster = new THREE.Raycaster();
let intersections = [];
const textureLoader = new THREE.TextureLoader();
const fontLoader = new THREE.FontLoader();
const font = "https://assets.codepen.io/2479807/silk-json.json";
const makePlane = (width, height, image) => {
const geometry = new THREE.PlaneBufferGeometry(width, height, 1);
const material = new THREE.MeshBasicMaterial({
side: THREE.DoubleSide,
map: image
});
const mesh = new THREE.Mesh(geometry, material);
return mesh;
};
const setImagesPositions = (image, index) => {
if (index === 0) {
// Top left
gsap.set(image, { x: -20, y: 20, z: "-=20" });
} else if (index === 1) {
// Bottom left
gsap.set(image, { x: -20, y: -20, z: "-=80" });
} else if (index === 2) {
// Top right
gsap.set(image, { x: 20, y: 20, z: "-=40" });
} else if (index === 3) {
// Bottom right
gsap.set(image, { x: 20, y: -20, z: "-=120" });
}
return;
};
const months = [];
sectionsInfo.forEach((section, index) => {
const sectionGroup = new THREE.Group();
fontLoader.load(font, (font) => {
const geometry = new THREE.TextBufferGeometry(section.title, {
font: font,
size: 6,
height: 0,
curveSegments: 4
}).center();
const material = new THREE.MeshBasicMaterial({
//color: 0x404e7c
color: 0x00a1d7
});
const mesh = new THREE.Mesh(geometry, material);
sectionGroup.add(mesh);
});
section.images.forEach((image, index) => {
const plane = makePlane(
20,
20,
textureLoader.load(image, (texture) => {
plane.scale.set(
1.0,
texture.image.height / texture.image.width,
1.0
);
})
);
intersections.push(plane);
setImagesPositions(plane.position, index);
sectionGroup.add(plane);
months.push(sectionGroup);
});
gsap.set(sectionGroup.position, {
z: () => -index * 200
});
scene.add(sectionGroup);
});
let mouse = new THREE.Vector2();
let mousePerspective = {
x: 0,
y: 0
};
const onMouseMove = (event) => {
mouse.set(
(event.clientX / window.innerWidth) * 2 - 1,
(event.clientX / window.innerWidth) * -2 + 1
);
raycaster.intersectObjects(intersections, true).forEach((intersection) => {
console.log("Over");
// intersection.object.scale.divideScalar(1.5);
});
mousePerspective.x = event.clientX / window.innerWidth - 0.5;
mousePerspective.y = event.clientY / window.innerHeight - 0.5;
gsap.to(camera.rotation, 4, {
x: -mousePerspective.y * 0.5,
y: -mousePerspective.x * 0.5,
ease: "power4.out"
});
};
window.addEventListener("mousemove", onMouseMove, false);
const onWindowResize = () => {
viewport.width = container.clientWidth;
viewport.height = container.clientHeight;
viewport.aspectRatio = container.clientWidth / container.clientHeight;
camera.aspect = viewport.aspectRatio;
camera.updateProjectionMatrix();
renderer.setSize(viewport.width, viewport.height);
};
window.addEventListener("resize", onWindowResize);
document.addEventListener("mousewheel", (event) => {
camera.position.z -= (event.deltaY / 10) * 0.25;
});
const render = () => {
renderer.render(scene, camera);
raycaster.setFromCamera(mouse, camera);
requestAnimationFrame(() => {
render();
});
};
render();